package com.crane.oss.school.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.crane.common.core.dto.SingleResponse;
import com.crane.common.core.exception.AppException;
import com.crane.common.core.exception.BasicErrorCode;
import com.crane.common.core.exception.SysException;
import com.crane.common.core.utils.CollectionUtil;
import com.crane.common.core.utils.StringUtil;
import com.crane.common.framework.utils.BeanUtil;
import com.crane.common.framework.utils.DateUtil;
import com.crane.oss.api.bean.resp.StudentClassResp;
import com.crane.oss.api.bean.resp.StudentResponse;
import com.crane.oss.app.bean.req.AppUpdatePicReq;
import com.crane.oss.app.bean.request.mqtt.UpdateModeResp;
import com.crane.oss.app.bean.resp.AppStudentInfo;
import com.crane.oss.app.bean.resp.AppUserResp;
import com.crane.oss.app.service.AppUserService;
import com.crane.oss.enums.ClassesStatusEnum;
import com.crane.oss.enums.ClassesTypeEnum;
import com.crane.oss.enums.DelFlagEnum;
import com.crane.oss.enums.GradeEnum;
import com.crane.oss.enums.SexEnum;
import com.crane.oss.school.bean.request.QueryStudentReq;
import com.crane.oss.school.bean.request.QueryWaitingStudentReq;
import com.crane.oss.school.bean.request.student.AddLayerClassesReq;
import com.crane.oss.school.bean.request.student.AddStudentReq;
import com.crane.oss.school.bean.request.student.AppUpdateStudentReq;
import com.crane.oss.school.bean.request.student.BatchChangeStudentReq;
import com.crane.oss.school.bean.request.student.BatchDeleteStudentReq;
import com.crane.oss.school.bean.request.student.BatchImportStudentEntity;
import com.crane.oss.school.bean.request.student.BatchUpdateSnReq;
import com.crane.oss.school.bean.request.student.ChangeStudentInfo;
import com.crane.oss.school.bean.request.student.ChangeStudentReq;
import com.crane.oss.school.bean.request.student.DeleteStudentInfo;
import com.crane.oss.school.bean.request.student.DeleteStudentReq;
import com.crane.oss.school.bean.request.student.StudentInfo;
import com.crane.oss.school.bean.request.student.UpdateStudentReq;
import com.crane.oss.school.bean.resp.ClassesInfoResp;
import com.crane.oss.school.bean.resp.StudentExportResp;
import com.crane.oss.school.bean.resp.StudentParentsResp;
import com.crane.oss.school.bean.resp.StudentResp;
import com.crane.oss.school.bean.resp.StudentSimpleResp;
import com.crane.oss.school.bean.resp.StudentWebDto;
import com.crane.oss.school.dao.ClassesInfoDao;
import com.crane.oss.school.dao.EquipmentDao;
import com.crane.oss.school.dao.StudentChangeClassDao;
import com.crane.oss.school.dao.StudentClassDao;
import com.crane.oss.school.dao.StudentDao;
import com.crane.oss.school.dao.StudentEquipmentDao;
import com.crane.oss.school.dao.StudentUserDao;
import com.crane.oss.school.model.ClassesInfo;
import com.crane.oss.school.model.Equipment;
import com.crane.oss.school.model.Student;
import com.crane.oss.school.model.StudentChangeClass;
import com.crane.oss.school.model.StudentClass;
import com.crane.oss.school.model.StudentEquipment;
import com.crane.oss.school.model.StudentUser;
import com.crane.oss.school.service.ClassesInfoService;
import com.crane.oss.school.service.StudentService;
import com.crane.oss.school.syn.SynXunfeiService;
import com.crane.oss.sports.XunFeiPushEventApiService;

import lombok.extern.slf4j.Slf4j;

/**
 * @author zhenxing.pi
 * @email ccsu123456@qq.com
 * @date 2022年03月26日 14时24分54秒
 */
@Service
@Slf4j
public class StudentServiceImpl implements StudentService {

	@Resource
	protected StudentDao studentDao;

	@Autowired
	protected AppUserService appUserService;

	@Resource
	protected StudentUserDao studentUserDao;

	@Resource
	protected ClassesInfoDao classesInfoDao;

	@Autowired
	protected ClassesInfoService classesInfoService;

	@Resource
	protected StudentClassDao studnetClassDao;

	@Resource
	protected StudentChangeClassDao studentChangeClassDao;

	@Resource
	protected StudentEquipmentDao studentEquipmentDao;

	@Resource
	EquipmentDao equipmentDao;

	@Resource
	SynXunfeiService synXunfeiService;

	@Override
	public StudentResp queryStudentOnInit(Long studentId) {
		log.info("StudentServiceImpl queryStudentOnInit studentId={}", studentId);
		Student queryStudent = studentDao.selectById(studentId);
		StudentResp studentResp = new StudentResp();
		BeanUtil.copyProperties(queryStudent, studentResp);
		return studentResp;
	}

	@Override
	public StudentResp queryStudent(Long studentId) {
		log.info("StudentServiceImpl queryStudent studentId={}", studentId);
		StudentWebDto student = studentDao.queryStudentDetails(studentId);
		if (null == student) {
			throw new AppException(BasicErrorCode.ENTITY_NOT_EXISTS, "学生");
		}
		StudentResp studentResp = new StudentResp();
		BeanUtil.copyProperties(student, studentResp);

		studentResp.setGradeName(GradeEnum.getGradeEnum(student.getGrade()));
		studentResp.setSexCn(SexEnum.getRemark(student.getSex()));
		studentResp.setStatusCn(ClassesStatusEnum.getRemark(student.getStatus()));

		List<StudentParentsResp> appUserList = new ArrayList<StudentParentsResp>();
		List<AppUserResp> queryList = appUserService.queryAppUserForStudent(studentId);
		for (AppUserResp appUser : queryList) {
			StudentParentsResp resp = new StudentParentsResp();
			resp.setPhone(appUser.getMobile());
			resp.setIdentity(appUser.getIdentity());
			resp.setAppUserId(appUser.getAppUserId());
			resp.setCreateTime(appUser.getCreateTime());

			appUserList.add(resp);
		}

		studentResp.setAppUserList(appUserList);

		List<String> layerInfo = new ArrayList<String>();
		List<ClassesInfoResp> classesList = classesInfoService.queryClassesForStudent(studentId);
		for (ClassesInfoResp classes : classesList) {
			layerInfo.add(classes.getClassName());
		}
		studentResp.setLayerInfo(layerInfo);

		return studentResp;
	}

	@Override
	public IPage<StudentSimpleResp> waiting(QueryWaitingStudentReq queryRequest) {
		log.info("StudentServiceImpl queryList queryRequest={}", queryRequest);
		Map<String, Object> map = BeanUtil.asMap(queryRequest);
		map.put("offset", queryRequest.getPageSize() * (queryRequest.getPageNo() - 1));
		map.put("limit", queryRequest.getPageSize());
		int total = studentDao.queryWaitingTotal(map);

		IPage<StudentSimpleResp> result = new Page<>();
		result.setCurrent(queryRequest.getPageNo());
		result.setPages(queryRequest.getPageSize());
		List<StudentSimpleResp> resultList = new ArrayList<>();
		result.setRecords(resultList);
		result.setTotal(total);
		if (total == 0) {
			return result;
		}

		List<Student> queryList = studentDao.queryWaitingList(map);
		for (Student student : queryList) {
			StudentSimpleResp resp = new StudentSimpleResp();
			resp.setStudentId(student.getStudentId());
			resp.setName(student.getName());
			resp.setSn(student.getSn());

			resultList.add(resp);
		}

		result.setRecords(resultList);
		return result;
	}

	@Override
	public List<StudentExportResp> queryExportList(QueryStudentReq request) {
		log.info("StudentServiceImpl queryList queryRequest={}", request);
		IPage<StudentResp> queryList = this.queryList(request);
		List<StudentExportResp> returnList = BeanUtil.copyList(queryList.getRecords(), StudentExportResp.class);
		return returnList;
	}

	@Override
	public IPage<StudentResp> queryList(QueryStudentReq queryRequest) {
		log.info("StudentServiceImpl queryList queryRequest={}", queryRequest);
		Map<String, Object> map = BeanUtil.asMap(queryRequest);
		map.put("offset", queryRequest.getPageSize() * (queryRequest.getPageNo() - 1));
		map.put("limit", queryRequest.getPageSize());
		int total = studentDao.queryListTotal(map);

		IPage<StudentResp> result = new Page<>();
		result.setCurrent(queryRequest.getPageNo());
		result.setPages(queryRequest.getPageSize());
		List<StudentResp> resultList = new ArrayList<>();
		result.setRecords(resultList);
		result.setTotal(total);
		if (total == 0) {
			return result;
		}

		List<StudentWebDto> queryList = studentDao.queryList(map);

		for (StudentWebDto student : queryList) {
			StudentResp resultResp = new StudentResp();
			BeanUtil.copyProperties(student, resultResp);

			resultResp.setGradeName(GradeEnum.getGradeEnum(student.getGrade()));
			resultResp.setSexCn(SexEnum.getRemark(student.getSex()));
			resultResp.setStatusCn(ClassesStatusEnum.getRemark(student.getStatus()));
			resultResp.setClassType(ClassesTypeEnum.getRemark(student.getClassType()));

			resultList.add(resultResp);
		}

		result.setRecords(resultList);
		return result;
	}

	@Override
	public IPage<StudentResp> queryStudentClassList(QueryStudentReq request) {
		log.info("StudentServiceImpl queryStudentClassList queryRequest={}", request);
		IPage<StudentResp> result = new Page<>();
		result.setCurrent(request.getPageNo());
		result.setPages(request.getPageSize());
		IPage<StudentResp> page = studentDao
				.selectPageStudentList(new Page<>(request.getPageNo(), request.getPageSize()), request);
		return page;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void join(AddLayerClassesReq addRequest) {
		log.info("StudentServiceImpl join addRequest={}", addRequest);

		List<Long> studentIds = addRequest.getStudentId();

		for (Long studentId : studentIds) {
			StudentClass queryStudentClass = studnetClassDao.selectOne(Wrappers.lambdaQuery(StudentClass.class)
					.eq(StudentClass::getStudentId, studentId)
					.eq(StudentClass::getClassId, addRequest.getClassId())
					.eq(StudentClass::getDelFlag, 0));
			if (null != queryStudentClass) {
				studentIds.remove(studentId);
			}
		}

		try {
			for (Long studentId : studentIds) {
				StudentClass studentClass = new StudentClass();
				studentClass.setStudentId(studentId);
				studentClass.setClassId(addRequest.getClassId());
				studentClass.setDelFlag(0);
				studentClass.setCreateTime(new Date());
				studentClass.setCreateUserId(addRequest.getCreateUesrId());
				studnetClassDao.insert(studentClass);

				StudentClassResp studentClassResp=new StudentClassResp();
				studentClassResp.setStudentId(studentId.toString());
				studentClassResp.setClassId(addRequest.getClassId().toString());
				ClassesInfo classesInfo = classesInfoDao.selectById(addRequest.getClassId());
				studentClassResp.setClassType(classesInfo.getType().toString());
				synXunfeiService.pushDate(studentClassResp, XunFeiPushEventApiService.EVENT_REF_STUDENT_CLASS,XunFeiPushEventApiService.INSERT,classesInfo.getPartyId().toString(),addRequest.getCreateUesrId().toString());
			}
		} catch (Exception e) {
			log.info("StudentServiceImpl save e={}", e);
			throw new SysException();
		}
	}

	@Override
	public boolean queryStudentSNExisit(String sn, Long partyId) {
		log.info("StudentServiceImpl save sn={},partyId={}", sn, partyId);
		List<Student> queryStudent = studentDao.selectList(Wrappers.lambdaQuery(Student.class)
				.eq(Student::getSn, sn)
				.eq(Student::getPartyId, partyId)
				.eq(Student::getDelFlag, 0));
		if (CollectionUtil.isNotEmpty(queryStudent)) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void batchSave(List<BatchImportStudentEntity> entityList, Long partyId, Long createUserId, Long schoolId,
			Integer grade, Long classId) {
		log.info("StudentServiceImpl batchSave partyId={},createUserId={},schoolId={},grade={},classId={}", partyId,
				createUserId, schoolId, grade, classId);
		for (BatchImportStudentEntity entity : entityList) {
			AddStudentReq addRequest = new AddStudentReq();
			addRequest.setName(entity.getName());
			addRequest.setSex(entity.getSex());
			addRequest.setSchoolId(schoolId);
			addRequest.setClassId(classId);
			addRequest.setTermBeginTime(entity.getTermBeginTime());
			addRequest.setNumber(entity.getNumber());
			addRequest.setSn(entity.getSn());
			addRequest.setPartyId(partyId);
			addRequest.setBirthday(entity.getBirthday());
			addRequest.setHeight(Integer.valueOf(entity.getHeight()));
			addRequest.setWeight(Integer.valueOf(entity.getWeight()));
			addRequest.setCreateUesrId(createUserId);

			this.save(addRequest);
		}

	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int save(AddStudentReq addRequest) {
		log.info("StudentServiceImpl save request={}", addRequest);
		if (queryStudentSNExisit(addRequest.getSn(), addRequest.getPartyId())) {
			throw new AppException(BasicErrorCode.ENTITY_IS_EXISTS, "学号");
		}

		Student student = new Student();
		BeanUtil.copyProperties(addRequest, student);

		if (StringUtil.isNotBlank(addRequest.getBirthday())) {
			student.setBirthday(DateUtil.parsePageDate(addRequest.getBirthday()));
		}

		int i = 0;
		try {
			student.setDelFlag(0);
			student.setStatus(1);
			student.setCreateTime(new Date());
			student.setCreateUserId(addRequest.getCreateUesrId());
			i = studentDao.insert(student);

			StudentClass studentClass = new StudentClass();
			studentClass.setStudentId(student.getStudentId());
			studentClass.setClassId(addRequest.getClassId());
			studentClass.setDelFlag(0);
			studentClass.setCreateTime(new Date());
			studentClass.setCreateUserId(addRequest.getCreateUesrId());
			studnetClassDao.insert(studentClass);


			StudentResponse studentResponse=new StudentResponse();
			studentResponse.setId(student.getStudentId().toString());
			studentResponse.setName(student.getName());
			studentResponse.setSchoolNumber(student.getSn());
			studentResponse.setCountryNumber(student.getNumber().toString());
			studentResponse.setGender(student.getSex() == 0 ? "1" :"2");
			if(null != student.getBirthday()){
				studentResponse.setBirthDate(DateUtil.format(DateUtil.TIME_PATTERN, student.getBirthday()));
			}
			studentResponse.setPhone("");
			synXunfeiService.pushDate(studentResponse, XunFeiPushEventApiService.EVENT_STUDENT,XunFeiPushEventApiService.INSERT,student.getPartyId().toString(),addRequest.getCreateUesrId().toString());

			StudentClassResp studentClassResp=new StudentClassResp();
			studentClassResp.setStudentId(student.getStudentId().toString());
			studentClassResp.setClassId(addRequest.getClassId().toString());
			ClassesInfo classesInfo = classesInfoDao.selectById(addRequest.getClassId());
			studentClassResp.setClassType(classesInfo.getType().toString());
			synXunfeiService.pushDate(studentClassResp, XunFeiPushEventApiService.EVENT_REF_STUDENT_CLASS,XunFeiPushEventApiService.INSERT,student.getPartyId().toString(),addRequest.getCreateUesrId().toString());

		} catch (Exception e) {
			log.info("StudentServiceImpl save e={}", e);
			throw new SysException();
		}
		return i;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int update(UpdateStudentReq updateRequest) {
		log.info("StudentServiceImpl update request={}", updateRequest);
		Student queryStudent = studentDao.selectById(updateRequest.getStudentId());
		if (null == queryStudent) {
			throw new AppException(BasicErrorCode.ENTITY_NOT_EXISTS, "学生");
		}
		if (StringUtil.isNotBlank(updateRequest.getSn()) && !updateRequest.getSn().equals(queryStudent.getSn())) {
			if (queryStudentSNExisit(updateRequest.getSn(), updateRequest.getPartyId())) {
				throw new AppException(BasicErrorCode.ENTITY_IS_EXISTS, "学号");
			}
		}

		Date now = new Date();
		Student updateStudent = new Student();
		BeanUtil.copyProperties(updateRequest, updateStudent);

		if (StringUtil.isNotBlank(updateRequest.getBirthday())) {
			updateStudent.setBirthday(DateUtil.parsePageDate(updateRequest.getBirthday()));
		}

		int i = 0;
		try {
			updateStudent.setUpdateTime(now);
			updateStudent.setUpdateUserId(updateRequest.getUpdateUserId());
			i = studentDao.updateById(updateStudent);

			StudentResponse studentResponse=new StudentResponse();
			studentResponse.setId(updateStudent.getStudentId().toString());
			studentResponse.setName(updateStudent.getName() == null ? queryStudent.getName() : updateStudent.getName());
			studentResponse.setSchoolNumber(updateStudent.getSn() == null ? queryStudent.getSn() : updateStudent.getSn());
			studentResponse.setCountryNumber(updateStudent.getNumber() == null ? queryStudent.getNumber().toString() : updateStudent.getNumber().toString());
			Integer sex=updateStudent.getSex() == null ? queryStudent.getSex() : updateStudent.getSex();
			studentResponse.setGender(sex == 0 ? "1" :"2");
			Date birthday=updateStudent.getBirthday() == null ? queryStudent.getBirthday() : updateStudent.getBirthday();
			studentResponse.setBirthDate(DateUtil.format(DateUtil.TIME_PATTERN, birthday));
			studentResponse.setPhone("");
			synXunfeiService.pushDate(studentResponse, XunFeiPushEventApiService.EVENT_STUDENT,XunFeiPushEventApiService.UPDATE,queryStudent.getPartyId().toString(),queryStudent.getCreateUserId().toString());


			if (null != updateRequest.getUnbindUserIdList()) {
				for (Long userId : updateRequest.getUnbindUserIdList()) {
					StudentUser studentUser = studentUserDao.selectOne(Wrappers.lambdaQuery(StudentUser.class)
							.eq(StudentUser::getStudentId, updateRequest.getStudentId())
							.eq(StudentUser::getAppUserId, userId));
					if (null != studentUser) {
						studentUser.setDelFlag(0);// 是否关联标志 0否 1是
						studentUser.setUpdateTime(now);
						studentUser.setUpdateUserId(updateRequest.getUpdateUserId());
						studentUserDao.updateById(studentUser);
					}
				}
			}

		} catch (Exception e) {
			log.info("StudentServiceImpl update e={}", e);
			throw new SysException();
		}
		return i;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void batchDelete(BatchDeleteStudentReq request) {
		log.info("StudentServiceImpl batchDelete request={}", request);
		Date now = new Date();
		try {
			for (DeleteStudentInfo student : request.getStudentList()) {
				Student queryStudent = studentDao.selectById(student.getStudentId());
				if (null != queryStudent) {
					if (ClassesTypeEnum.layered_classes.getType().equals(request.getClassType())) {
						// 删除学生分层班信息
						List<StudentClass> studentClassList = studnetClassDao.queryStudentClass(student.getStudentId(),student.getClassId());
						for (StudentClass studentClass : studentClassList) {
							studentClass.setDelFlag(DelFlagEnum.YES.getType());
							studentClass.setUpdateTime(now);
							studentClass.setUpdateUserId(request.getUpdateUserId());
							studnetClassDao.updateById(studentClass);
							synStudentClass(queryStudent, studentClass, ClassesTypeEnum.layered_classes.getType().toString());
						}
					} else {
						// 删除学生行政班、分层班信息
						List<StudentClass> studentClassList = studnetClassDao.selectList(
								Wrappers.lambdaQuery(StudentClass.class).eq(StudentClass::getDelFlag, DelFlagEnum.NO.getType())
										.eq(StudentClass::getStudentId, student.getStudentId()));
						for (StudentClass studentClass : studentClassList) {
							studentClass.setDelFlag(DelFlagEnum.YES.getType());
							studentClass.setUpdateTime(now);
							studentClass.setUpdateUserId(request.getUpdateUserId());
							studnetClassDao.updateById(studentClass);
							synStudentClass(queryStudent, studentClass, ClassesTypeEnum.common_classes.getType().toString());
						}

						// 解绑家长关联信息
						List<StudentUser> studentUserList = studentUserDao.selectList(Wrappers.lambdaQuery(StudentUser.class)
								.eq(StudentUser::getDelFlag, 1).eq(StudentUser::getStudentId, student.getStudentId()));
						for (StudentUser studentUser : studentUserList) {
							studentUser.setDelFlag(0);// 是否关联标志 0否 1是
							studentUser.setUpdateTime(now);
							studentUser.setUpdateUserId(request.getUpdateUserId());
							studentUserDao.updateById(studentUser);
						}
						// 删除学生信息
						queryStudent.setUpdateTime(now);
						queryStudent.setUpdateUserId(request.getUpdateUserId());
						queryStudent.setDelFlag(DelFlagEnum.YES.getType());
						studentDao.updateById(queryStudent);

						StudentResponse studentResponse=new StudentResponse();
						studentResponse.setId(student.getStudentId().toString());
						synXunfeiService.pushDate(studentResponse, XunFeiPushEventApiService.EVENT_STUDENT,XunFeiPushEventApiService.DELETE,queryStudent.getPartyId().toString(),queryStudent.getCreateUserId().toString());

					}
				}
			}
		} catch (Exception e) {
			log.info("StudentServiceImpl batchDelete e={}", e);
			throw new SysException();
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int delete(DeleteStudentReq request) {
		log.info("StudentServiceImpl delete request={}", request);
		Long studentId = request.getStudentId();
		Student queryStudent = studentDao.selectById(studentId);
		if (null == queryStudent) {
			throw new AppException(BasicErrorCode.ENTITY_NOT_EXISTS, "学生");
		}

		int i = 0;
		Date now = new Date();
		try {

			if (ClassesTypeEnum.layered_classes.getType().equals(request.getClassType())) {
				// 删除学生分层班信息
				List<StudentClass> studentClassList = studnetClassDao.queryStudentClass(studentId,request.getClassId());
				for (StudentClass studentClass : studentClassList) {
					studentClass.setDelFlag(DelFlagEnum.YES.getType());
					studentClass.setUpdateTime(now);
					studentClass.setUpdateUserId(request.getUpdateUserId());
					studnetClassDao.updateById(studentClass);
					synStudentClass(queryStudent, studentClass, ClassesTypeEnum.layered_classes.getType().toString());
				}
			} else {
				// 删除学生行政班、分层班信息
				List<StudentClass> studentClassList = studnetClassDao.selectList(
						Wrappers.lambdaQuery(StudentClass.class).eq(StudentClass::getDelFlag, DelFlagEnum.NO.getType())
								.eq(StudentClass::getStudentId, studentId));
				for (StudentClass studentClass : studentClassList) {
					studentClass.setDelFlag(DelFlagEnum.YES.getType());
					studentClass.setUpdateTime(now);
					studentClass.setUpdateUserId(request.getUpdateUserId());
					studnetClassDao.updateById(studentClass);
					synStudentClass(queryStudent,studentClass, ClassesTypeEnum.common_classes.getType().toString());
				}

				// 解绑家长关联信息
				List<StudentUser> studentUserList = studentUserDao.selectList(Wrappers.lambdaQuery(StudentUser.class)
						.eq(StudentUser::getDelFlag, 1).eq(StudentUser::getStudentId, studentId));
				for (StudentUser studentUser : studentUserList) {
					studentUser.setDelFlag(0);// 是否关联标志 0否 1是
					studentUser.setUpdateTime(now);
					studentUser.setUpdateUserId(request.getUpdateUserId());
					studentUserDao.updateById(studentUser);
				}
				// 删除学生信息
				queryStudent.setUpdateTime(now);
				queryStudent.setUpdateUserId(request.getUpdateUserId());
				queryStudent.setDelFlag(DelFlagEnum.YES.getType());
				i = studentDao.updateById(queryStudent);

				StudentResponse studentResponse=new StudentResponse();
				studentResponse.setId(queryStudent.getStudentId().toString());
				synXunfeiService.pushDate(studentResponse, XunFeiPushEventApiService.EVENT_STUDENT,XunFeiPushEventApiService.DELETE,queryStudent.getPartyId().toString(),queryStudent.getCreateUserId().toString());
			}
		} catch (Exception e) {
			log.info("StudentServiceImpl delete e={}", e);
			throw new SysException();
		}
		return i;
	}

	private void synStudentClass(Student queryStudent, StudentClass studentClass, String classType) {
		StudentClassResp studentClassResp = new StudentClassResp();
		studentClassResp.setStudentId(studentClass.getStudentId().toString());
		studentClassResp.setClassId(studentClass.getClassId().toString());
		studentClassResp.setClassType(classType);
		synXunfeiService.pushDate(studentClassResp, XunFeiPushEventApiService.EVENT_REF_STUDENT_CLASS, XunFeiPushEventApiService.DELETE, queryStudent.getPartyId().toString(), queryStudent.getCreateUserId().toString());
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void batchChange(BatchChangeStudentReq request) {
		log.info("StudentServiceImpl batchChange request={}", request);
		Date date = new Date();
		try {
			for (ChangeStudentInfo changeInfo : request.getChangeStudentInfo()) {
				Student queryStudent = studentDao.selectById(changeInfo.getStudentId());
				if (null != queryStudent) {
					ClassesInfoResp beforeClasses = this.classesInfoService.queryClassesInfo(changeInfo.getBeforeClassId());
					ClassesInfoResp currentClasses = this.classesInfoService.queryClassesInfo(request.getCurrentClassId());
					if ((beforeClasses.getGrade() == currentClasses.getGrade()) && (changeInfo.getBeforeClassId() != request.getCurrentClassId())) {
						StudentChangeClass newStudentChangeClass = new StudentChangeClass();
						newStudentChangeClass.setStudentId(changeInfo.getStudentId());
						newStudentChangeClass.setBeforeGrade(beforeClasses.getGrade());
						newStudentChangeClass.setBeforeSn(queryStudent.getSn());
						newStudentChangeClass.setBeforeSchoolId(changeInfo.getBeforeSchoolId());
						newStudentChangeClass.setBeforeClassId(changeInfo.getBeforeClassId());
						newStudentChangeClass.setCurrentSchoolId(request.getCurrentSchoolId());
						newStudentChangeClass.setCurrentClassId(request.getCurrentClassId());
						newStudentChangeClass.setCreateTime(date);
						newStudentChangeClass.setCreateUserId(request.getUpdateUserId());
						studentChangeClassDao.insert(newStudentChangeClass);

						Student updateStudent = new Student();
						updateStudent.setStudentId(changeInfo.getStudentId());
						updateStudent.setSchoolId(request.getCurrentSchoolId());
						updateStudent.setUpdateTime(date);
						updateStudent.setUpdateUserId(request.getUpdateUserId());
						studentDao.updateById(updateStudent);

						StudentClass studentClass = studnetClassDao.selectOne(Wrappers.lambdaQuery(StudentClass.class)
								.eq(StudentClass::getDelFlag, DelFlagEnum.NO.getType()).eq(StudentClass::getStudentId, changeInfo.getStudentId())
								.eq(StudentClass::getClassId, changeInfo.getBeforeClassId()));
						studentClass.setClassId(request.getCurrentClassId());
						studentClass.setUpdateTime(date);
						studentClass.setUpdateUserId(request.getUpdateUserId());
						studnetClassDao.updateById(studentClass);

						ClassesInfo classesInfo = classesInfoDao.selectById(studentClass.getClassId());
						StudentClassResp studentClassResp = new StudentClassResp();
						studentClassResp.setStudentId(studentClass.getStudentId().toString());
						studentClassResp.setClassId(studentClass.getClassId().toString());
						studentClassResp.setClassType(classesInfo.getType().toString());
						synXunfeiService.pushDate(studentClassResp, XunFeiPushEventApiService.EVENT_REF_STUDENT_CLASS, XunFeiPushEventApiService.UPDATE, queryStudent.getPartyId().toString(), queryStudent.getCreateUserId().toString());
					}
				}
			}
		} catch (Exception e) {
			log.info("StudentServiceImpl batchChange e={}", e);
			throw new SysException();
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int change(ChangeStudentReq request) {
		log.info("StudentServiceImpl change request={}", request);
		Long studentId = request.getStudentId();
		Student queryStudent = studentDao.selectById(studentId);
		if (null == queryStudent) {
			throw new AppException(BasicErrorCode.ENTITY_NOT_EXISTS, "学生");
		}

		// 可以跨校区但是不可以跨年级转班
		ClassesInfoResp beforeClasses = this.classesInfoService.queryClassesInfo(request.getBeforeClassId());
		ClassesInfoResp currentClasses = this.classesInfoService.queryClassesInfo(request.getCurrentClassId());
		if (beforeClasses.getGrade() != currentClasses.getGrade()) {
			throw new AppException(BasicErrorCode.DEFINED_MSG, "不能跨年级转班");
		}
		if (request.getBeforeClassId() == request.getCurrentClassId()) {
			throw new AppException(BasicErrorCode.DEFINED_MSG, "不能同班级异动");
		}

		int i = 0;
		Date now = new Date();
		try {
			StudentChangeClass newStudentChangeClass = new StudentChangeClass();
			newStudentChangeClass.setStudentId(studentId);
			newStudentChangeClass.setBeforeGrade(beforeClasses.getGrade());
			newStudentChangeClass.setBeforeSn(queryStudent.getSn());
			newStudentChangeClass.setBeforeSchoolId(request.getBeforeSchoolId());
			newStudentChangeClass.setBeforeClassId(request.getBeforeClassId());
			newStudentChangeClass.setCurrentSchoolId(request.getCurrentSchoolId());
			newStudentChangeClass.setCurrentClassId(request.getCurrentClassId());
			newStudentChangeClass.setCreateTime(now);
			newStudentChangeClass.setCreateUserId(request.getUpdateUserId());
			i = studentChangeClassDao.insert(newStudentChangeClass);

			Student updateStudent = new Student();
			updateStudent.setStudentId(studentId);
			updateStudent.setSchoolId(request.getCurrentSchoolId());
			updateStudent.setUpdateTime(now);
			updateStudent.setUpdateUserId(request.getUpdateUserId());
			studentDao.updateById(updateStudent);

			StudentClass studentClass = studnetClassDao.selectOne(Wrappers.lambdaQuery(StudentClass.class)
					.eq(StudentClass::getDelFlag, DelFlagEnum.NO.getType()).eq(StudentClass::getStudentId, studentId)
					.eq(StudentClass::getClassId, request.getBeforeClassId()));
			studentClass.setClassId(request.getCurrentClassId());
			studentClass.setUpdateTime(now);
			studentClass.setUpdateUserId(request.getUpdateUserId());
			studnetClassDao.updateById(studentClass);

			ClassesInfo classesInfo = classesInfoDao.selectById(studentClass.getClassId());
			StudentClassResp studentClassResp = new StudentClassResp();
			studentClassResp.setStudentId(studentClass.getStudentId().toString());
			studentClassResp.setClassId(studentClass.getClassId().toString());
			studentClassResp.setClassType(classesInfo.getType().toString());
			synXunfeiService.pushDate(studentClassResp, XunFeiPushEventApiService.EVENT_REF_STUDENT_CLASS, XunFeiPushEventApiService.UPDATE, queryStudent.getPartyId().toString(), queryStudent.getCreateUserId().toString());
		} catch (Exception e) {
			log.info("StudentServiceImpl change e={}", e);
			throw new SysException();
		}
		return i;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void batchUpdate(BatchUpdateSnReq request) {
		log.info("StudentServiceImpl batchUpdate request={}", request);
		Date now = new Date();
		try {
			for (StudentInfo info : request.getUpdateList()) {
				Student queryStudent = studentDao.selectById(info.getStudentId());
				if (null != queryStudent) {
					queryStudent.setNumber(Integer.valueOf(info.getSn()));
					queryStudent.setUpdateUserId(request.getUpdateUserId());
					queryStudent.setUpdateTime(now);
					studentDao.updateById(queryStudent);

					StudentResponse studentResponse=new StudentResponse();
					studentResponse.setId(queryStudent.getStudentId().toString());
					studentResponse.setName(queryStudent.getName());
					studentResponse.setSchoolNumber(queryStudent.getSn());
					studentResponse.setCountryNumber(queryStudent.getNumber().toString());
					Integer sex=queryStudent.getSex();
					studentResponse.setGender(sex == 0 ? "1" :"2");
					Date birthday=queryStudent.getBirthday();
					studentResponse.setBirthDate(DateUtil.format(DateUtil.TIME_PATTERN, birthday));
					studentResponse.setPhone("");
					synXunfeiService.pushDate(studentResponse, XunFeiPushEventApiService.EVENT_STUDENT,XunFeiPushEventApiService.UPDATE,queryStudent.getPartyId().toString(),queryStudent.getCreateUserId().toString());
				}
			}
		} catch (Exception e) {
			log.info("StudentServiceImpl batchUpdate e={}", e);
			throw new SysException();
		}
	}

	@Override
	public List<AppStudentInfo> appQueryStudentInfo(Long appUserId) {
		List<AppStudentInfo> list = studentDao.appQueryStudentInfo(appUserId);
		return list;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateUserPicUrl(AppUpdatePicReq appUpdatePicReq) {
		Student student = new Student();
		student.setStudentId(appUpdatePicReq.getId());
		student.setImg(appUpdatePicReq.getPicUrl());
		studentDao.updateById(student);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public SingleResponse<UpdateModeResp> appUpdateStudent(AppUpdateStudentReq request) {
		log.info("StudentServiceImpl appUpdateStudent request={}", request);
		Student queryStudent = studentDao.selectById(request.getStudentId());
		if (null == queryStudent) {
			throw new AppException(BasicErrorCode.ENTITY_NOT_EXISTS, "学生");
		}
		Student updateStudent = new Student();
		Date now = new Date();
		updateStudent.setStudentId(request.getStudentId());
		updateStudent.setWeight(request.getWeight());
		updateStudent.setUpdateTime(now);
		studentDao.updateById(updateStudent);
		try {
			List<StudentEquipment> studentEquipmentList=studentEquipmentDao.selectList(Wrappers.lambdaQuery(StudentEquipment.class)
					.eq(StudentEquipment ::getStudentId,request.getStudentId()));
			if(CollectionUtil.isNotEmpty(studentEquipmentList)){
				for(StudentEquipment studentEquipment : studentEquipmentList){
					Equipment dbEquipment=equipmentDao.selectById(studentEquipment.getEquipmentId());
					if(null != dbEquipment){
						UpdateModeResp resp=new  UpdateModeResp();
						resp.setBindType(studentEquipment.getBindType());
						resp.setImei(dbEquipment.getImei());
						return SingleResponse.of(resp);
					}
				}
			}
		} catch (Exception e) {
			log.info("StudentServiceImpl appUpdateStudent e={}", e);
			throw new SysException();
		}
		return SingleResponse.of(null);
	}

}
